package com.ruoyi.media.mediaLogin.controller;

import com.alibaba.fastjson.JSONObject;
import com.dtflys.forest.http.ForestResponse;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.redis.RedisUtils;
import com.ruoyi.media.forestApi.common.WechatMiniProRequest;
import com.ruoyi.media.forestApi.common.WechatMpUtilApiRequest;
import com.ruoyi.media.forestApi.vo.BaseResVo;
import com.ruoyi.media.mediaLogin.domain.BaseMessage;
import com.ruoyi.media.mediaLogin.domain.bo.MediaLoginBo;
import com.ruoyi.media.mediaLogin.service.IMediaLoginService;
import com.ruoyi.media.mediaLogin.service.WechatBaseUtil;
import com.ruoyi.media.utils.WxUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import static com.ruoyi.media.mediaLogin.service.WechatBaseUtil.*;
import static com.ruoyi.media.mediaLogin.service.impl.MediaLoginServiceImpl.wxTokenKey;

@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/wechatService")
public class MediaLoginController extends BaseController {

    /**
     * 小程序请求接口方法
     */
    private final WechatMiniProRequest wechatMiniProRequest;
    /**
     * 公众号登录接口请求
     */
    private final WechatMpUtilApiRequest wechatMpUtilApiRequest;
    /**
     * 登录方法业务类
     */
    private final IMediaLoginService mediaLoginService;
    /**
     * 登录业务类
     */
//    private final SysLoginService sysLoginService;


    @Value("${wxgzh.appId}")
    private String appId;

    @Value("${wxgzh.appSecret}")
    private String appSecret;

    /**
     * 公众号服务器配置token
     */
    @Value("${wxgzh.token}")
    private String wxToken;



    /**
     * 获取公众号二维码
     */
    @GetMapping("/scanQRLogin")
    public R<?> scanQRLogin(){
        try{
            ArrayList<String> params = wechatMpUtilApiRequest.getScanQR();
            return R.ok(params);
        }catch (Exception e){
            System.out.println(e.getMessage());
        }
        return R.warn("系统异常！");
    }


    /**
     * 获取小程序登录码
     */
    @GetMapping("/createQRCode")
    public R<?> createQRCode() throws Exception {
        Map<String, Object> resData = new HashMap<>();
        //获取微信小程序accessToken
        String wxAccessToken = mediaLoginService.getWxMiniAccessToken();
        //生成36位二维码校验参数
        String ticket = WxUtils.getRandomNumber(24);
        System.out.println(ticket);
        //添加到redis
        mediaLoginService.setTicketByRedis(ticket);
        System.out.println(ticket);
        //请求二维码接口
        ForestResponse qrCodeData = wechatMiniProRequest.wxParamQRCode(wxAccessToken, ticket);
        if(qrCodeData.getContent().contains("40001")){
            RedisUtils.deleteObject(wxTokenKey);
        }
        //封装返回参数
        resData.put("scanQRCode", qrCodeData.getByteArray());
        resData.put("ticket", ticket);
        return R.ok(resData);
    }




    /**
     * 用户扫小程序码登录
     */
//    @GetMapping("/scanMiniQRCode")
//    public R<?> scanMiniQRCode(MediaLoginBo bo) {
//        Map<String,Object> resMap = new HashMap<>();
//        //获取当前小程序openid
//        BaseResVo baseResVo = wechatMiniProRequest.jscode2session(bo.getCode());
//        String openId = baseResVo.getOpenid();
//        //查询数据库是否存在当前账号数据
//        SysUser resSysUser = sysUserService.getUserByOpenid(openId);
//        if(resSysUser != null){
//            //登录
//            String token = sysLoginService.autoLogin(resSysUser.getUserName());
//            resMap.put("status",1); //已登录
//            resMap.put("token",token);
////            resMap.put("sysUser",resSysUser);
//        }else{
////            if(bo.getUserInfo() != null && bo.getUserInfo().contains("userInfo")){
////                JSONObject userInfo = JSONObject.parseObject(bo.getUserInfo());
////                JSONObject userData = userInfo.getJSONObject("userInfo");
////                String avatarUrl = XStringUtils.getNullBlankStr(userData.getString("avatarUrl"));
////                String gender = XStringUtils.getNullBlankStr(userData.getString("gender"));
////                String nickName = XStringUtils.getNullBlankStr(userData.getString("nickName"));
////                String userName =  WxUtils.getRandomStr(12);
////                SysUser sysUser = new SysUser();
////                sysUser.setOpenid(bo.getOpenid());
////                sysUser.setNickName(nickName);
////                sysUser.setAvatar(avatarUrl);
////                sysUser.setSex(gender);
////                sysUser.setUserName(userName);
////                sysUser.setUserType("sys_user");
////                boolean regFlag = sysUserService.registerUser(sysUser);
////                if (!regFlag) {
////                    throw new UserException("user.register.error");
////                }
////                //登录
////                String token = sysLoginService.autoLogin(userName);
////                resMap.put("status",1); //已登录
////                resMap.put("token",token);
////            }else{
////
////            }
//            resMap.put("status",-1); //用户未注册
//            resMap.put("openId",openId);
//        }
//        RedisUtils.setCacheObject(bo.getTicket(),resMap,Duration.ofMinutes(10));
//        return R.ok(resMap);
//    }


    /**
     * pc端获取小程序登录token
     */
    @GetMapping("/getScanCode/{ticket}")
    public R<?> getScanCode(@PathVariable String ticket) {
        Map<String,Object> resMap = RedisUtils.getCacheObject(ticket);
        return R.ok(resMap);
    }


    /**
     * 获取公众号二维码
     */
    @GetMapping("/scanMpQRLogin")
    public R<?> scanMpQRLogin(){
        try{
            ArrayList<String> params = wechatMpUtilApiRequest.getScanQR();
            return R.ok(params);
        }catch (Exception e){
        }
        return R.warn("系统异常！");
    }



    /**
     * 校验微信服务器token
     * @param response
     * @throws Exception
     */
    @GetMapping("/callBack")
    public void callBack(String signature, String timestamp, String nonce, String echostr, HttpServletResponse response) throws Exception{
        String[] str = { wxToken, timestamp, nonce };
        // 字典排序
        Arrays.sort(str);
        String bigStr = str[0] + str[1] + str[2];
        // SHA1加密
        String digest = WxUtils.sha1(bigStr);
        // 确认请求来至微信
        if (digest.equals(signature)) {
            response.getWriter().print(echostr);
        }
    }






    /**
     * 接收微信的回调
     * @param response
     * @param request
     * @throws Exception
     */
    @PostMapping("/callBack")
    @Transactional(rollbackFor = Exception.class)
    public void callBack(HttpServletResponse response, HttpServletRequest request) throws Exception{
        R<JSONObject> result = new R<JSONObject>();
        try {
            //防止消息乱码
            request.setCharacterEncoding("UTF-8");
            response.setCharacterEncoding("UTF-8");
            //响应
            PrintWriter out = null;
            String respMessage = "";

            Map<String, Object> map = WechatBaseUtil.parseXml(request);
            BaseMessage baseMessage = WechatBaseUtil.mapToBean(map,BaseMessage.class);

            if(baseMessage.getMsgType().equals(REQ_MESSAGE_TYPE_EVENT)){  //推送事件
                if(StringUtils.isEmpty(baseMessage.getFromUserName())){
                    return;
                }
//                SysUser resUser = sysUserService.getById(baseMessage.getFromUserName()); //查询账号是否为空
                if("resUser" == null){   //没有该用户则创建
                    try{
//                        sysUserService.saveOpenId(baseMessage.getFromUserName());  //创建扫码用户
                    }catch (Exception e){
//                        log.info(e.getMessage());
                        return;
                    }
                }
//                SysUser sysUser = sysUserService.getById(baseMessage.getFromUserName()); //查询当前已创建的用户
                if(baseMessage.getEvent().equals(EVENT_TYPE_SUBSCRIBE)){ //事件类型为订阅
                    if(baseMessage.getTicket() != null){
//                        saveLoginTicket(baseMessage.getTicket(),sysUser,result); //将扫码结果保存到redis
                    }
                    //封装消息体
                    respMessage =  WechatBaseUtil.sendMessageByContent(baseMessage,EVENT_TYPE_SUBSCRIBE);
//                    log.info("用户:{}",baseMessage.getFromUserName());
                }else if(baseMessage.getEvent().equals(EVENT_TYPE_SCAN)){ //事件类型为扫码
                    if(baseMessage.getTicket() != null){
//                        saveLoginTicket(baseMessage.getTicket(),sysUser,result); //将扫码结果保存到redis
                    }
//                    log.info("用户扫码:{}",baseMessage.getFromUserName());
                } else if(baseMessage.getEvent().equals(EVENT_TYPE_UNSUBSCRIBE)){ //用户取关
//                    log.info("用户取消关注:{}",baseMessage.getFromUserName());
                }
            }else if(baseMessage.getMsgType().equals(REQ_MESSAGE_TYPE_TEXT)){ //获取的内容为文本
                if(StringUtils.isNotEmpty(baseMessage.getContent())){  //逻辑处理
                    //封装消息体
                    respMessage =  WechatBaseUtil.sendMessageByContent(baseMessage,REQ_MESSAGE_TYPE_TEXT);
                }
//                log.info("用户发送消息:{}",baseMessage.getFromUserName());
//                log.info("消息内容:{}",baseMessage.getContent());
            }

            //包含消息则发送
            if(StringUtils.isNotEmpty(respMessage)){
                response.setCharacterEncoding("UTF-8");
                out = response.getWriter();
                out.write(respMessage);
            }

        } catch (Exception e) {
//            log.info(e.getMessage());
        }
    }




    /**
     * 检测扫码登录状态
     * @throws Exception
     */
    @GetMapping("/checkLoginStatus")
    public R<?> checkLoginStatus(@RequestParam(value = "ticket",required = true) String ticket){
        R<JSONObject> result = new R<>();
        try{
            Map<String,Object> res = RedisUtils.getCacheObject(ticket);
            if(res != null){
                String message = "";
                if(res.get("status").toString().equals("1")){
                    message = "扫码成功！";
                }else if(res.get("status").toString().equals("0")){
                    message = "未扫码！";
                }else {
                    message = "扫码失败！";
                }
                JSONObject data = new JSONObject(res);
                result.setData(data);
            }
        }catch (Exception e){
//            log.info(e.getMessage());
        }
        return result;
    }



    /**
     * 登录将参数保存redis
     */
    public void saveLoginTicket(String ticket,SysUser sysUser,R<JSONObject> result){
        Map<String,Object> statusMap = new HashMap<>();
        if(StringUtils.isNotEmpty(sysUser.getPhonenumber())){
//            wechatServiceSerImp.userInfo(sysUser, result);
            statusMap.put("status",1);  //状态为已登录
            statusMap.put("dataMap",result);
            RedisUtils.setCacheObject(ticket,statusMap,Duration.ofMinutes(60)); // 将账号扫码状态变更为已登录
        }else{
            statusMap.put("status",2);  //未绑定手机号的用户
            statusMap.put("dataMap",sysUser);
            RedisUtils.setCacheObject(ticket,statusMap,Duration.ofMinutes(60)); // 将账号扫码状态变更为已登录
        }
    }





}
